{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1bc669c4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前最佳位置：[25.         19.73406565 17.52000381 11.48492263 15.49049632]\n",
      "当前的最佳适应度：1420949410334.44\n",
      "当前最佳位置：[25.         19.80381853 17.06061173 10.90937177 16.01073366]\n",
      "当前的最佳适应度：1425971959842.59\n",
      "当前最佳位置：[25.         19.85962084 16.69309807 10.44893109 16.42692353]\n",
      "当前的最佳适应度：1429989999449.03\n",
      "当前最佳位置：[25.         19.90426269 16.39908714 10.08057854 16.75987543]\n",
      "当前的最佳适应度：1433204431134.14\n",
      "当前最佳位置：[25.         20.22077895 15.39908714 11.08057854 17.75987543]\n",
      "当前的最佳适应度：1455995152854.37\n",
      "当前最佳位置：[25.         21.80295213  7.22293939 12.30742305 17.87339884]\n",
      "当前的最佳适应度：1569919373353.78\n",
      "当前最佳位置：[25.         22.72237368  7.52898743 13.30742305 17.54032309]\n",
      "当前的最佳适应度：1636122229342.27\n",
      "当前最佳位置：[25.         23.72237368  8.50771858 14.30742305 16.58207875]\n",
      "当前的最佳适应度：1708127128676.32\n",
      "当前最佳位置：[25.         24.55499863  9.24345447 15.21676216 15.8653065 ]\n",
      "当前的最佳适应度：1768080204390.38\n",
      "当前最佳位置：[25.         25.         11.33424857 15.87800434 16.02133971]\n",
      "当前的最佳适应度：1800122483465.04\n",
      "当前最佳位置：[25.         25.          9.5811044  17.04325335 15.70879352]\n",
      "当前的最佳适应度：1800122483466.13\n",
      "当前最佳位置：[25.         25.         10.88100117 17.08680466 17.57643303]\n",
      "当前的最佳适应度：1800122483467.87\n",
      "当前最佳位置：[25.         25.         10.76863234 18.08680466 18.51472967]\n",
      "当前的最佳适应度：1800122483469.82\n",
      "当前最佳位置：[25.         25.          9.42966258 19.24127523 19.36076381]\n",
      "当前的最佳适应度：1800122483472.0\n",
      "当前最佳位置：[25.         25.          8.76863234 20.08680466 20.51472967]\n",
      "当前的最佳适应度：1800122483474.08\n",
      "当前最佳位置：[25.         25.          7.46584537 21.14251229 21.23435754]\n",
      "当前的最佳适应度：1800122483476.03\n",
      "当前最佳位置：[25.         25.          7.98346379 21.87579245 22.80831998]\n",
      "当前的最佳适应度：1800122483478.27\n",
      "当前最佳位置：[25.         25.          6.98346379 22.87579245 23.80831998]\n",
      "当前的最佳适应度：1800122483480.4\n",
      "当前最佳位置：[25.         25.          5.89236621 23.9833137  24.86511241]\n",
      "当前的最佳适应度：1800122483482.71\n",
      "当前最佳位置：[25.         25.          4.54586548 25.         25.        ]\n",
      "当前的最佳适应度：1800122483484.04\n",
      "当前最佳位置：[25.         25.          3.16586453 25.         25.        ]\n",
      "当前的最佳适应度：1800122483484.22\n",
      "当前最佳位置：[25.         25.          2.04970382 25.         25.        ]\n",
      "当前的最佳适应度：1800122483484.37\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n",
      "当前最佳位置：[25. 25.  1. 25. 25.]\n",
      "当前的最佳适应度：1800122483484.51\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import math\n",
    "import random\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pylab as mpl\n",
    "mpl.rcParams['font.sans-serif'] = ['SimHei']\n",
    "\n",
    "\n",
    "class PSO:\n",
    "    def __init__(self, dimension, time, size, low, up, v_low, v_high):\n",
    "        # 初始化\n",
    "        self.dimension = dimension  # 变量个数\n",
    "        self.time = time  # 迭代的代数\n",
    "        self.size = size  # 种群大小\n",
    "        self.bound = []  # 变量的约束范围\n",
    "        self.bound.append(low)\n",
    "        self.bound.append(up)\n",
    "        self.v_low = v_low\n",
    "        self.v_high = v_high\n",
    "        self.x = np.zeros((self.size, self.dimension))  # 所有粒子的位置\n",
    "        self.v = np.zeros((self.size, self.dimension))  # 所有粒子的速度\n",
    "        self.p_best = np.zeros((self.size, self.dimension))  # 每个粒子最优的位置\n",
    "        self.g_best = np.zeros((1, self.dimension))[0]  # 全局最优的位置\n",
    "\n",
    "        # 初始化第0代初始全局最优解\n",
    "        temp = -1000000\n",
    "        for i in range(self.size):\n",
    "            for j in range(self.dimension):\n",
    "                self.x[i][j] = random.uniform(self.bound[0][j], self.bound[1][j])\n",
    "                self.v[i][j] = random.uniform(self.v_low, self.v_high)\n",
    "            self.p_best[i] = self.x[i]  # 储存最优的个体\n",
    "            fit = self.fitness(self.p_best[i])\n",
    "            # 做出修改\n",
    "            if fit > temp:\n",
    "                self.g_best = self.p_best[i]\n",
    "                temp = fit\n",
    "\n",
    "    def fitness(self, x):\n",
    "        \"\"\"\n",
    "        个体适应值计算\n",
    "        \"\"\"\n",
    "        x1 = x[0]\n",
    "        x2 = x[1]\n",
    "        x3 = x[2]\n",
    "        x4 = x[3]\n",
    "        x5 = x[4]\n",
    "        y = math.floor((x2 * np.exp(x1) + x3 * np.sin(x2) + x4 + x5) * 100) / 100\n",
    "        # print(y)\n",
    "        return y\n",
    "\n",
    "    def update(self, size):\n",
    "        c1 = 2.0  # 学习因子\n",
    "        c2 = 2.0\n",
    "        w = 0.8  # 自身权重因子\n",
    "        for i in range(size):\n",
    "            # 更新速度(核心公式)\n",
    "            self.v[i] = w * self.v[i] + c1 * random.uniform(0, 1) * (\n",
    "                    self.p_best[i] - self.x[i]) + c2 * random.uniform(0, 1) * (self.g_best - self.x[i])\n",
    "            # 速度限制\n",
    "            for j in range(self.dimension):\n",
    "                if self.v[i][j] < self.v_low:\n",
    "                    self.v[i][j] = self.v_low\n",
    "                if self.v[i][j] > self.v_high:\n",
    "                    self.v[i][j] = self.v_high\n",
    "\n",
    "            # 更新位置\n",
    "            self.x[i] = self.x[i] + self.v[i]\n",
    "            # 位置限制\n",
    "            for j in range(self.dimension):\n",
    "                if self.x[i][j] < self.bound[0][j]:\n",
    "                    self.x[i][j] = self.bound[0][j]\n",
    "                if self.x[i][j] > self.bound[1][j]:\n",
    "                    self.x[i][j] = self.bound[1][j]\n",
    "            # 更新p_best和g_best\n",
    "            if self.fitness(self.x[i]) > self.fitness(self.p_best[i]):\n",
    "                self.p_best[i] = self.x[i]\n",
    "            if self.fitness(self.x[i]) > self.fitness(self.g_best):\n",
    "                self.g_best = self.x[i]\n",
    "\n",
    "    def pso(self):\n",
    "        best = []\n",
    "        self.final_best = np.array([1, 2, 3, 4, 5])\n",
    "        for gen in range(self.time):\n",
    "            self.update(self.size)\n",
    "            if self.fitness(self.g_best) > self.fitness(self.final_best):\n",
    "                self.final_best = self.g_best.copy()\n",
    "            print('当前最佳位置：{}'.format(self.final_best))\n",
    "            temp = self.fitness(self.final_best)\n",
    "            print('当前的最佳适应度：{}'.format(temp))\n",
    "            best.append(temp)\n",
    "        t = [i for i in range(self.time)]\n",
    "        plt.figure()\n",
    "        plt.plot(t, best, color='red', marker='.', ms=15)\n",
    "        plt.rcParams['axes.unicode_minus'] = False\n",
    "        plt.margins(0)\n",
    "        plt.xlabel(u\"迭代次数\")  # X轴标签\n",
    "        plt.ylabel(u\"适应度\")  # Y轴标签\n",
    "        plt.title(u\"迭代过程\")  # 标题\n",
    "        plt.show()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    time = 50\n",
    "    size = 100\n",
    "    dimension = 5\n",
    "    v_low = -1\n",
    "    v_high = 1\n",
    "    low = [1, 1, 1, 1, 1]\n",
    "    up = [25, 25, 25, 25, 25]\n",
    "    pso = PSO(dimension, time, size, low, up, v_low, v_high)\n",
    "    pso.pso()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5855f50",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:gluon] *",
   "language": "python",
   "name": "conda-env-gluon-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
